package com.dhl.utils;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Transactional;

@Transactional
public class BaseDaoImpl<T> implements BaseDao<T> {

	@Resource
    private SessionFactory sessionFactory;
    protected Class<T> clazz;
    
    @SuppressWarnings({ "unchecked", "rawtypes" })
	public BaseDaoImpl() {
    	 Type type = this.getClass().getGenericSuperclass();//拿到父类类型
         //判断是否是ParameterizedType类型，是就转换
    	 if (type instanceof ParameterizedType) {
             ParameterizedType genType = (ParameterizedType) type;
             this.clazz = (Class) genType.getActualTypeArguments()[0];
         } else {
             throw new RuntimeException( "没有继承类");
         }
    }
    
    /**
     * 获取会话
     * @return
     */
    protected Session getSession() {
        return sessionFactory.getCurrentSession();
    }

	@SuppressWarnings("unchecked")
	@Override
	public boolean delete(String id) {
		 try {
			 T object = (T) getSession().get(clazz, id);
			 getSession().delete(object);
			 return true;
		} catch (HibernateException e) {
			e.printStackTrace();
			return false;
		}
	}

	@Override
	public boolean delete(T entity) {
		try {
			 getSession().delete(entity);
			 return true;
		} catch (HibernateException e) {
			e.printStackTrace();
			return false;
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public T getById(String id) {
		try {
			 return (T) getSession().get(clazz, id);
		} catch (HibernateException e) {
			e.printStackTrace();
			return null;
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public T getBySearch(String hql, List<Object> values) {
		try {
			 Query query = getSession().createQuery("from " + clazz.getSimpleName() + hql);
			 if(Utils.isNotNull(values)){
				 for(int i = 0,len = values.size();i < len;++i){
					 query.setParameter(i, values.get(i));
				 }
			 }
			 List<T> list = query.list();
			 if(list != null && list.size() > 0){
				 return list.get(0);
			 }
			 return null;
		} catch (HibernateException e) {
			e.printStackTrace();
			return null;
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> getAll() {
		try {
			 Query query = getSession().createQuery("from " + clazz.getSimpleName());
			 return query.list();
		} catch (HibernateException e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public int getTotalCount() {
		try {
			int count = ((Long)getSession().createQuery("select count(*) from " + clazz.getSimpleName()).uniqueResult()).intValue();
			return count;
		} catch (HibernateException e) {
			e.printStackTrace();
			return 0;
		}
	}

	@Override
	public int getSearchCount(String hql, List<Object> values) {
		try {
			 Query query = getSession().createQuery("select count(*) from " + clazz.getSimpleName() + hql);
			 if(Utils.isNotNull(values)){
				 for(int i = 0,len = values.size();i < len;++i){
					 query.setParameter(i, values.get(i));
				 }
			 }
			 int count = ((Long)query.list().get(0)).intValue();
			 return count;
		} catch (HibernateException e) {
			e.printStackTrace();
			return 0;
		}
	}

	@Override
	public T save(T entity) {
		String id = (String) getSession().save(entity);
		return this.getById(id);
	}

	@Override
	public boolean saveAll(List<T> list) {
		boolean flag = true;//false失败
		Session session = null;  
        if (list != null && list.size() > 0) {  
            try {  
                session = getSession(); // 获取Session  
                session.beginTransaction(); // 开启事物  
                for (int i = 0; i < list.size(); i++) {  
                	session.save(list.get(i));
                	if(i != 0 && i % 2000 == 0){//每二千条添加一次
                		session.flush();  
                        session.clear();
                	}
                }  
                session.flush();  
                session.clear();  
                flag = true;
            } catch (RuntimeException e) {  
            	flag = false;
                e.printStackTrace(); // 打印错误信息  
                throw e;//事务回滚
            }
        }
        return flag;
	}

	@Override
	public T update(T entity) {
		try {
			getSession().update(entity);
			return entity;
		} catch (HibernateException e) {
			e.printStackTrace();
			return null;
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> getSearch(String hql, List<Object> values) {
		try {
			 Query query = getSession().createQuery("from " + clazz.getSimpleName() + hql);
			 if(Utils.isNotNull(values)){
				 for(int i = 0,len = values.size();i < len;++i){
					 query.setParameter(i, values.get(i));
				 }
			 }
			 return query.list();
		} catch (HibernateException e) {
			e.printStackTrace();
			return null;
		}
	}


	@Override
	public void delOrUpdateSQL(String sql, List<Object> values) {
		Query query = getSession().createSQLQuery(sql);
		if(Utils.isNotNull(values)){
			 for(int i = 0,len = values.size();i < len;++i){
				 query.setParameter(i, values.get(i));
			 }
		 }
		query.executeUpdate();
	}

	@Override
	public void rmSession(T entity) {
		getSession().delete(entity);
	}

	@Override
	public void clearSession() {
		getSession().clear();
	}
    
    
    
}
